package logic

import (
	"context"
	"time"

	"mall/common/errorx"
	"mall/service/backend/model"
	"mall/service/backend/rpc/internal/svc"
	"mall/service/backend/rpc/types/backend"

	"github.com/zeromicro/go-zero/core/logx"
)

type BackendUpdateRoleLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewBackendUpdateRoleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BackendUpdateRoleLogic {
	return &BackendUpdateRoleLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *BackendUpdateRoleLogic) BackendUpdateRole(in *backend.UpdateRoleRequest) (*backend.UpdateRoleResponse, error) {
	if in.Id == 0 {
		return nil, errorx.Status(errorx.ERROR_ROLE_ID_REQUIRED, "")
	}

	var columns []string = []string{model.BackendRoleColumns.RoleID}
	if len(in.PermIds) > 0 {
		role, err := l.svcCtx.BackendRole.FindOne(l.ctx, in.Id, columns)
		if err != nil {
			return nil, err
		}

		perms, _, err := l.svcCtx.BackendPermission.GetList(l.ctx, model.M{
			"ids":                                 in.PermIds,
			"select":                              ",",
			model.BackendPermissionColumns.Status: 1,
		}, -1)
		if err != nil {
			return nil, err
		}

		err = l.svcCtx.BackendRole.SetPerms(l.ctx, role, perms)
		if err != nil {
			return nil, err
		}
	} else if len(in.MenuIds) > 0 {
		role, err := l.svcCtx.BackendRole.FindOne(l.ctx, in.Id, columns)
		if err != nil {
			return nil, err
		}

		menus, _, err := l.svcCtx.BackendMenu.GetList(l.ctx, model.M{
			"ids":                           in.MenuIds,
			"select":                        ",",
			model.BackendMenuColumns.Status: 1,
		}, -1)
		if err != nil {
			return nil, err
		}

		err = l.svcCtx.BackendRole.SetMenus(l.ctx, role, menus)
		if err != nil {
			return nil, err
		}
	} else {
		var pageSize int64 = 2
		roleList, _, err := l.svcCtx.BackendRole.GetList(l.ctx, model.M{
			model.BackendRoleColumns.Name: in.Name,
			"pageSize":                    pageSize,
			"select":                      ",",
		}, -1)
		if err != nil {
			return nil, err
		}
		count := len(roleList)
		if count > 1 {
			return nil, errorx.Status(errorx.ERROR_ROLE_NAME_EXISTS, "")
		}
		if count == 1 && roleList[0].RoleID != uint64(in.Id) {
			return nil, errorx.Status(errorx.ERROR_ROLE_NAME_EXISTS, "")
		}

		var role model.BackendRole
		role.RoleID = uint64(in.Id)
		role.Name = in.Name
		role.Note = in.Note
		role.Status = uint8(in.Status)
		role.DelStatus = uint8(in.Status)
		role.LastUpdatedBy = uint64(in.UpdatedBy)
		role.UpdatedAt = time.Now()
		_, err = l.svcCtx.BackendRole.Update(l.ctx, &role)
		if err != nil {
			return nil, err
		}
	}

	return &backend.UpdateRoleResponse{}, nil
}
